﻿using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StockholmsStad.Web.UI.Class.Controller;
using StockholmsStad.Web.UI.Class.Interfaces;
using StockholmsStad.Web.UI.Class.Model;
using StockholmsStad.Web.UI.Class.Utilities;
using StockholmsStad.Web.UI.UIServiceReference;

namespace StockholmsStad.Web.UI.Test
{
    /// <summary>
    ///This is a test class for BookingControllerTest and is intended
    ///to contain all BookingControllerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class BookingControllerTest
    {
        #region Delegates

        public delegate bool IsAuthenticated();

        #endregion

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        /// <summary>
        ///A test for SubmitBooking
        ///</summary>
        [TestMethod()]
        public void SubmitBookingTest()
        {
            var mocks = new MockRepository();
            var _confirmView = mocks.StrictMock<IBokning3_Confirm>();
            var session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var serviceFacade = mocks.StrictMock<IServiceFacade>();
            IHttpContextAdapter context = mocks.StrictMock<IHttpContextAdapter>();
            User user = new User();
            Booking booking = new Booking();
            LoginModel loginModel = new LoginModel(session, serviceFacade, context);
            loginModel.User = user;
            var model = new BookingModel(session, serviceFacade) {Booking = booking};
            var target = new BookingController(model, loginModel, _confirmView);
            Expect.Call(context.IsAuthenticated()).Return(true);
            Expect.Call(() => serviceFacade.RegisterBooking(user, booking));
            mocks.ReplayAll();
            target.SubmitBooking();
            mocks.VerifyAll();
        }

        public static bool GetIsAuthenticated(IsAuthenticated callback)
        {
            return callback();
        }

        /// <summary>
        ///A test for ChooseBookingTimes
        ///</summary>
        [TestMethod()]
        public void ChooseBookingTimesTest()
        {
            var mocks = new MockRepository();
            var _confirmView = mocks.StrictMock<IBokning3_Confirm>();
            var session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            IHttpContextAdapter context = mocks.StrictMock<IHttpContextAdapter>();
            var model = new BookingModel(session, facade);
            LoginModel loginModel = new LoginModel(session, facade, context);
            var target = new BookingController(model, loginModel, _confirmView);
            Booking bookingDateTime = Booking.createOrdinaryBooking(null, null, null);
            Expect.Call(context.IsAuthenticated()).Return(false);
            Expect.Call(() => _confirmView.UpdateBooking(bookingDateTime, "Stadshuset"));
            mocks.ReplayAll();
            target.ChooseBookingTimes(bookingDateTime);
            Assert.AreEqual(model.Booking, bookingDateTime);
            Assert.IsTrue(model.Booking.BookingMadeBeforeLogin);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for ChooseBookingTimes. Logged in
        ///</summary>
        [TestMethod()]
        public void ChooseBookingTimesTest2()
        {
            var mocks = new MockRepository();
            var _confirmView = mocks.StrictMock<IBokning3_Confirm>();
            var session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            IHttpContextAdapter context = mocks.StrictMock<IHttpContextAdapter>();
            var model = new BookingModel(session, facade);
            LoginModel loginModel = new LoginModel(session, facade, context);
            var target = new BookingController(model, loginModel, _confirmView);
            Booking bookingDateTime = Booking.createOrdinaryBooking(null, null, null);
            Expect.Call(context.IsAuthenticated()).Return(true);
            Expect.Call(() => _confirmView.UpdateBooking(bookingDateTime, "Stadshuset"));
            mocks.ReplayAll();
            target.ChooseBookingTimes(bookingDateTime);
            Assert.AreEqual(model.Booking, bookingDateTime);
            Assert.IsFalse(model.Booking.BookingMadeBeforeLogin);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for BookingController Constructor
        ///</summary>
        [TestMethod()]
        public void BookingControllerConstructorTest()
        {
            var mocks = new MockRepository();
            var _confirmView = mocks.StrictMock<IBokning3_Confirm>();
            var session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var facade = mocks.StrictMock<IServiceFacade>();
            IHttpContextAdapter context = mocks.StrictMock<IHttpContextAdapter>();
            var model = new BookingModel(session, facade);
            LoginModel loginModel = new LoginModel(session, facade, context);
            mocks.ReplayAll();
            var target = new BookingController(model, loginModel, _confirmView);
            Assert.IsNotNull(target);
            mocks.VerifyAll();
        }
    }
}